#include "mwin.h"
#include "ui_mwin.h"
#include <QUrl>
#include <QDebug>
#include <QMessageBox>
#include <QCursor>
#include <QPrintDialog>
#include <QPrinter>
#include "base.h"

#define CFGNAME "rezervilo.cfg"

MWin::MWin(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MWin)
{

    QSettings cfg(QCoreApplication::applicationDirPath()+"/"+CFGNAME,QSettings::IniFormat);



    this->xmlclient = new xmlrpc::Client();
    this->xmlclient->setHost(cfg.value("server","").toString(),
                             cfg.value("port",5555).toInt());
    this->lang = cfg.value("lang","en").toString();
    // подключаем перевод
    QTranslator * transmain = new QTranslator();
    if(transmain->load(QString(":/lang/%1.qm").arg(this->lang))){
        QCoreApplication::installTranslator(transmain);
    }
    ui->setupUi(this);

    // меню для списка пользователей
    actAddUser = new QAction(tr("Add user"),this);
    actEditUser = new QAction(tr("Edit user "),this);
    actDelUser = new QAction(tr("Delete user"),this);
    connect(actAddUser,SIGNAL(triggered()),this,SLOT(slotAddUser()));
    connect(actEditUser,SIGNAL(triggered()),this,SLOT(slotEditUser()));
    connect(actDelUser,SIGNAL(triggered()),this,SLOT(slotDelUser()));
    this->ui->tw_users->installEventFilter(this);
    // --
    // соединяем wt_users с двойным кликом для редактирования.
    connect(this->ui->tw_users,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(slotEditUser()));
    // соединяем tabW_admin на предмет изменения вкладки
    connect(this->ui->tabW_admin,SIGNAL(currentChanged(int)),this,SLOT(slottabW_admin()));

    // меню для списка событий администратора
    this->ui->tw_events->installEventFilter(this);
    actAdminEventsAdd = new QAction(tr("Add event"),this);
    actAdminEventsEdit = new QAction(tr("Edit event"),this);
    actAdminEventsDublicate = new QAction(tr("Dublicate and edit event"),this);
    actAdminEventsDelete = new QAction(tr("Delete event"),this);
    connect(this->actAdminEventsAdd,SIGNAL(triggered()),this,SLOT(slotAdminEventsAdd()));
    connect(this->actAdminEventsEdit,SIGNAL(triggered()),this,SLOT(slotAdminEventsEdit()));
    connect(this->actAdminEventsDublicate,SIGNAL(triggered()),this,SLOT(slotAdminEventsDublicate()));
    connect(this->actAdminEventsDelete,SIGNAL(triggered()),this,SLOT(slotAdminEventsDelete()));
    // двойнок клик по списку событий администратора
    connect(this->ui->tw_events,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(slotAdminEventsEdit()));


    // меню для списка администратора тарифов
    this->ui->tw_tariffs->installEventFilter(this);
    actAdmTariffsAdd = new QAction(tr("Add tariff"),this);
    actAdmTariffsEdit = new QAction(tr("Edit tariff"),this);
    actAdmTariffsDel = new QAction(tr("Del tariff"),this);
    connect(this->actAdmTariffsAdd,SIGNAL(triggered()),this,SLOT(slotAdmTariffsAdd()));
    connect(this->actAdmTariffsEdit,SIGNAL(triggered()),this,SLOT(slotAdmTariffsEdit()));
    connect(this->actAdmTariffsDel,SIGNAL(triggered()),this,SLOT(slotAdmTariffsDel()));
    // двойнок клик
    connect(this->ui->tw_tariffs,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(slotAdmTariffsEdit()));

    // продажа билета - список событий
    connect(this->ui->btn_setCurrentWeek,SIGNAL(clicked()),this,SLOT(slotEventsUserSetCurrentWeek()));
    connect(this->ui->dte_de_user_evlist,SIGNAL(dateTimeChanged(QDateTime)),this,SLOT(slotSaleUpdateEventsList()));
    connect(this->ui->dte_gxis_user_evlist,SIGNAL(dateTimeChanged(QDateTime)),this,SLOT(slotSaleUpdateEventsList()));

    // администратор - отчеты
    connect(this->ui->lw_reports,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(slotReport()));

    // зануляем ids
    this->id_adduser=0;
    this->id_getuserslist=0;
    this->id_deluser=0;
    this->id_edituser=0;
    this->id_logon=0;
    this->id_adminEventsGet=0;
    this->id_adminEventAdd=0;
    this->id_adminEventAddTL=0;
    this->id_adminEventEdit=0;

    this->id_adminEventEditTL=0;
    this->id_adminEventEditTEL=0;

    this->id_admTariffsGet=0;
    this->id_admTariffsAdd=0;
    this->id_admTariffsEdit=0;
    this->id_admTariffsDel=0;

    this->id_userEventsList=0;
    this->id_userTariffsList = 0;
    this->id_userSaleTicket = 0;

    this->id_userReTicketInfo = 0;
    this->id_userReTicketBack = 0;

    this->id_user_tr = 0;

    this->id_PLugRequest = 0;

    // выставляем диапазон списка событий для администратора

    this->slotEventsAdminSetCurrentMonth();

    connect(this->ui->dte_de,SIGNAL(dateTimeChanged(QDateTime)),this,SLOT(slotAdminEventsUpdate()));
    connect(this->ui->dte_gxis,SIGNAL(dateTimeChanged(QDateTime)),this,SLOT(slotAdminEventsUpdate()));
    connect(this->ui->btn_cm,SIGNAL(clicked()),this,SLOT(slotEventsAdminSetCurrentMonth()));
    this->statusBar()->addWidget(&stlabel);

    this->hash="";
    this->usertype=0;
    this->username="";

    connect(this->xmlclient,SIGNAL(done(int,QVariant)),this,SLOT(slotDone(int,QVariant)));
    connect(this->xmlclient,SIGNAL(failed(int,int,QString)),this,SLOT(slotFail(int,int,QString)));
}

MWin::~MWin()
{
    delete ui;
}

void MWin::start(){



    // подключаем плагины отчетов
    qDebug()<<"start and open plugins";
    // необходимо получить список файлов из каталога плугинов которые помечены как отчеты
    // библиотеки находяться в подкаталоге plugins и для разных систем имеют разное окончание
    QDir a;
    a.cd(QCoreApplication::applicationDirPath()+"/plugins/");
    QStringList PluginsList;
    a.setFilter(QDir::Files);
    QStringList mask;
#ifdef Q_OS_MAC
    mask.append("librept*.dylib");
#endif
#ifdef Q_OS_LINUX
    mask.append("librept*.so");
#endif
#ifdef Q_OS_WIN32
    mask.append("librept*.dll");
#endif
    PluginsList = a.entryList(mask, QDir::Files);
    // инициируем плагины и добавляем их в спец список.
    QPluginLoader loader;
    iface_rept * plug;
    for(int i = 0 ; i < PluginsList.size() ; i++ ){
        // проверяем наличие файла из списка. и подклюаем при наличии
        if(QFile::exists(a.path()+"/"+PluginsList.at(i))){
            loader.setFileName(a.path()+"/"+PluginsList.at(i));
            if(loader.load()){
                plug = qobject_cast<iface_rept*>(loader.instance());
                // связываем плагин с механимзмом запроса
                connect(plug,SIGNAL(sigStartRequest(QString,QString,QStringList)),
                        this,SLOT(slotPlugRequestStart(QString,QString,QStringList)));
                connect(this,SIGNAL(sigPlugReguestFinish(QString,QString,QStringList)),
                        plug,SLOT(slotFinishRequest(QString,QString,QStringList)));
                if(plug->init(this->lang)){
                    reptList.append(plug);
                }
            }
        }
    }
    // плагины подключены, рисуем список.
    for(int i = 0 ; i < reptList.size(); i++){
        QListWidgetItem *item = new QListWidgetItem(reptList.at(i)->getName());
        this->ui->lw_reports->addItem(item);

    }

// запускаем главное окно =) сначала пробуем залогиниться на сервере, к которому уже подключились
    LogonDialog dia;
    dia.show();
    dia.raise();
    dia.activateWindow();
    if(dia.exec()){
        // вызываем процедуру авторизации
        QList<xmlrpc::Variant> params;
        params.append(dia.getLogin());
        this->username=dia.getLogin();
        params.append(dia.getPassword());
        params.append(QString(VERSION));
        this->logonKey=false;
        this->id_logon = this->xmlclient->request("logon",params);
//        while(!this->logonKey){
//            Sleeper::msleep(100);
//            QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
//        }
        this->dwait = new DiaWait;
        QString msgtext=tr("Connect to server");
        if(!this->dwait->start(1000 * 30
                              ,tr("Connect to server"),tr("%1\nPlease wait ...").arg(msgtext)) == QDialog::Accepted){
            // диалог был отменен
            if(this->dwait->isTimeouted()){
                // по таймауту
                QMessageBox::critical(NULL,tr("Error"),
                                      tr("Error connect to server.\n%1").arg(tr("Timeout"))
                                      ,QMessageBox::Ok);
                exit(2);
            }else{
                // отмена
                if(this->isWrkErr){
                    // отменен изза ошибки
                    // это ошибка получения информации
                    QMessageBox::critical(NULL,tr("Error"),
                                          tr("Error connect to server.\n%1").arg(this->lastError)
                                          ,QMessageBox::Ok);
                    exit(1);

                }else{
                    // отменен пользователем
                    exit(0);
                }

            }
        }else{
            // диалог отработал отлично
            delete this->dwait;
        }

    }else{
        exit(0);
    }

}

void MWin::slotDone(int id, QVariant variant){

    qDebug()<<"DONE -- "<<id<<" -- "<<variant;

    // ловим ответ от авторизации
    if(this->id_logon == id){
        // выставляем ключь авторизации и смотрим что пришло от сервера.
        this->dwait->slotStopOk();
        qDebug()<<"server return logon, hash"<<variant.toList().at(0).toString()<<" usertype "<<variant.toList().at(1).toInt();
        this->hash=variant.toList().at(0).toString();
        this->usertype=variant.toList().at(1).toInt();
        // судя по всему авторизация пройдена
        // подготавливаем окно и показываем его
        this->ui->stackedWidget->setCurrentIndex(this->usertype);
        switch(this->usertype){
        case 0:
            this->setWindowTitle(tr("Manager - %1").arg(this->username));
            this->ui->sw_user->setCurrentIndex(SALE_STAGE_0);
            break;
        case 1:
            this->setWindowTitle(tr("Administrator - %1").arg(this->username));
            this->ui->tabW_admin->setCurrentIndex(0);
            this->centralWidget()->setEnabled(false);
            this->stlabel.setText(tr("Query users list"));
            {
            // долбаная кроссинициализация =)
            QList<xmlrpc::Variant> np;
            np.append(this->username);
            np.append(this->hash);
            this->id_getuserslist = this->xmlclient->request("getuserslist",np);
            }
            break;
        default:
            break;
        }
        this->show();
    }
    // ответ от списка пользователей
    if(this->id_getuserslist == id){
        qDebug()<<"getuserslist";
        // прилетел список пользователей для админа.
        // очищаем табличку
        for(int i = this->ui->tw_users->rowCount(); i >= 0 ; i--){
            QTableWidgetItem * wit = this->ui->tw_users->takeItem(i,2);
            delete wit;
            wit = this->ui->tw_users->takeItem(i,1);
            delete wit;
            wit = this->ui->tw_users->takeItem(i,0);
            delete wit;
        }

        // заполняем табличку
        this->ui->tw_users->setRowCount(variant.toList().size()/3);
        int currentRow=0;
        for( int i = 0 ; i < variant.toList().size(); i=i+3){
            QTableWidgetItem * wit = new QTableWidgetItem;
            if(variant.toList().at(i).toInt() == UTYPE_USER){
                wit->setText(tr("User"));
                wit->setBackgroundColor("Green");
            }
            if(variant.toList().at(i).toInt() == UTYPE_ADMIN){
                wit->setText(tr("Admin"));
                wit->setBackgroundColor("Red");
            }

            this->ui->tw_users->setItem(currentRow,0,wit);
            wit = new QTableWidgetItem;
            wit->setText(variant.toList().at(i+1).toString());
            wit->setBackgroundColor(QColor(variant.toList().at(i+1).toString()));
            this->ui->tw_users->setItem(currentRow,1,wit);
            wit = new QTableWidgetItem;
            wit->setText(variant.toList().at(i+2).toString());
            this->ui->tw_users->setItem(currentRow,2,wit);
            currentRow++;
        }
        this->ui->tw_users->resizeColumnsToContents();
        this->ui->tw_users->horizontalHeader()->setStretchLastSection(true);
        this->stlabel.setText(tr("OK"));
        this->centralWidget()->setEnabled(true);
    }
    // ответ от добавления пользователя
    if(id == this->id_adduser){
        qDebug()<<"adduser";
        // запрашиваем список пользователей снова
        this->stlabel.setText(tr("Success add user and query users list"));
        QList<xmlrpc::Variant> np;
        np.append(this->username);
        np.append(this->hash);
        this->id_getuserslist = this->xmlclient->request("getuserslist",np);
    }
    // ответ на редактирование пользователя
    if(id == this->id_edituser){
        qDebug()<<"edituser";
        // запрашиваем список пользователей снова
        this->stlabel.setText(tr("Success edit user and query users list"));
        QList<xmlrpc::Variant> np;
        np.append(this->username);
        np.append(this->hash);
        this->id_getuserslist = this->xmlclient->request("getuserslist",np);
    }
    // ответ на удаление пользователя
    if(id == this->id_deluser){
        qDebug()<<"deluser";
        // запрашиваем список пользователей снова
        this->stlabel.setText(tr("Success del user and query users list"));
        QList<xmlrpc::Variant> np;
        np.append(this->username);
        np.append(this->hash);
        this->id_getuserslist = this->xmlclient->request("getuserslist",np);
    }
    // прилетел список событий для админа
    if( id == this->id_adminEventsGet ){
        qDebug()<<"adm.events.getlist";
        // очищаем табличку
        for(int i = this->ui->tw_events->rowCount(); i >= 0 ; i--){
            QTableWidgetItem * wit = this->ui->tw_events->takeItem(i,4);
            delete wit;
            wit = this->ui->tw_events->takeItem(i,3);
            delete wit;
            wit = this->ui->tw_events->takeItem(i,2);
            delete wit;
            wit = this->ui->tw_events->takeItem(i,1);
            delete wit;
            wit = this->ui->tw_events->takeItem(i,0);
            delete wit;

        }

        // заполняем табличку
        this->ui->tw_events->setRowCount(variant.toList().size()/6);
        int currentRow=0;
        for( int i = 0 ; i < variant.toList().size(); i=i+6){
            QTableWidgetItem * wit = new QTableWidgetItem;
            wit->setText(variant.toList().at(i).toString());
            wit->setToolTip(variant.toList().at(i+4).toString());
            this->ui->tw_events->setItem(currentRow,0,wit);
            wit = new QTableWidgetItem;

            switch (variant.toList().at(i+1).toInt()){
                case ESTATE_OPENED :
                wit->setText(tr("Opened"));
                wit->setBackgroundColor("Green");
                break;
                case ESTATE_CLOSED :
                wit->setText(tr("Closed"));
                wit->setBackgroundColor("Red");
                break;
                case ESTATE_HIDED :
                wit->setText(tr("Hided"));
                wit->setBackgroundColor("Grey");
                break;
            default:
                break;
            }
            wit->setToolTip(variant.toList().at(i+4).toString());
            this->ui->tw_events->setItem(currentRow,1,wit);

            wit = new QTableWidgetItem;
            wit->setText(variant.toList().at(i+2).toString());
            wit->setToolTip(variant.toList().at(i+4).toString());
            this->ui->tw_events->setItem(currentRow,2,wit);
            wit = new QTableWidgetItem;
            wit->setText(variant.toList().at(i+5).toString());
            wit->setToolTip(variant.toList().at(i+4).toString());
            this->ui->tw_events->setItem(currentRow,3,wit);
            wit = new QTableWidgetItem;
            wit->setText(variant.toList().at(i+3).toString());
            wit->setToolTip(variant.toList().at(i+4).toString());
            this->ui->tw_events->setItem(currentRow,4,wit);


            currentRow++;
        }
        this->ui->tw_events->resizeColumnsToContents();
        this->ui->tw_events->horizontalHeader()->setStretchLastSection(true);
        this->stlabel.setText(tr("OK"));
        this->centralWidget()->setEnabled(true);
    }

    // ответ от добавления события админом
    if(id == this->id_adminEventAdd){
        qDebug()<<"adm.events.add";
        // запрашиваем список событий снова
        this->stlabel.setText(tr("Success add event and query events list"));
        this->slotAdminEventsUpdate();
    }

    if(id == this->id_adminEventAddTL){
        qDebug()<<"adm.tariffs.getlist_for_events";
        // вынимаем список
        this->tariffslist.clear();
        for(int i = 0 ; i < variant.toList().size() ; i++ ){
            this->tariffslist.append(variant.toList().at(i).toString());
        }
        this->key_adminEventAdd=true;

    }

    if( id == this->id_adminEventEditTL){
        qDebug()<<"adm.tariffs.getlist_enabled_for_events_a";
        // вынимаем список
        this->tariffslist.clear();
        for(int i = 0 ; i < variant.toList().size() ; i++ ){
            this->tariffslist.append(variant.toList().at(i).toString());
        }
        this->key_11=true;
    }
    if( id == this->id_adminEventEditTEL){
        qDebug()<<"adm.tariffs.getlist_enabled_for_events_b";
        // вынимаем список
        this->tariffslistEnabled.clear();
        for(int i = 0 ; i < variant.toList().size() ; i++ ){
            this->tariffslistEnabled.append(variant.toList().at(i).toString());
        }
        this->key_adminEventEdit2=true;
    }


    // ответ на редактирование события админом
    if(id == this->id_adminEventEdit){
        qDebug()<<"adm.events.add";
        // запрашиваем список событий снова
        this->stlabel.setText(tr("Success add event and query events list"));
        this->slotAdminEventsUpdate();
    }

    // ответ на удаление события админом
    if(id == this->id_adminEventDel){
        qDebug()<<"adm.events.del";
        // запрашиваем список событий снова
        this->stlabel.setText(tr("Success delete event and query events list"));
        this->slotAdminEventsUpdate();
    }


    // ответ от списка тарифов
    if(this->id_admTariffsGet == id){
        qDebug()<<"adm.tariffs.getlist";
        // прилетел список тарифов для админа.
        // очищаем табличку
        for(int i = this->ui->tw_tariffs->rowCount(); i >= 0 ; i--){
            QTableWidgetItem * wit = this->ui->tw_users->takeItem(i,1);
            delete wit;
            wit = this->ui->tw_users->takeItem(i,0);
            delete wit;
        }

        // заполняем табличку
        this->ui->tw_tariffs->setRowCount(variant.toList().size()/2);
        int currentRow=0;
        for( int i = 0 ; i < variant.toList().size(); i=i+2){
            QTableWidgetItem * wit = new QTableWidgetItem;
            wit->setText(variant.toList().at(i).toString());
            this->ui->tw_tariffs->setItem(currentRow,0,wit);
            wit = new QTableWidgetItem;
            wit->setText(variant.toList().at(i+1).toString());
            this->ui->tw_tariffs->setItem(currentRow,1,wit);
            currentRow++;
        }
        this->ui->tw_tariffs->resizeColumnsToContents();
        this->ui->tw_tariffs->horizontalHeader()->setStretchLastSection(true);
        this->stlabel.setText(tr("OK"));
        this->centralWidget()->setEnabled(true);
    }
    // ответ от добавления тарифа админом
    if(id == this->id_admTariffsAdd){
        qDebug()<<"adm.tariffs.add";
        // запрашиваем список тарифов снова
        this->stlabel.setText(tr("Success add tariff and query tariffs list"));
        this->slotAdmTariffsUpdate();
    }
    // ответ на редактирование тарифа
    if(id == this->id_admTariffsEdit){
        qDebug()<<"adm.tariffs.add";
        // запрашиваем список тарифов снова
        this->stlabel.setText(tr("Success edit tariff and query tariffs list"));
        this->slotAdmTariffsUpdate();
    }
    //  ответ на удаление тарифа адимном
    if(id == this->id_admTariffsDel){
        qDebug()<<"adm.tariffs.del";
        // запрашиваем список тарифов снова
        this->stlabel.setText(tr("Success del tariff and query tariffs list"));
        this->slotAdmTariffsUpdate();
    }

    // ответ на получения списка событий пользователю
    if(id == this->id_userEventsList){
        qDebug()<<"user.events.getlist";
        // очищаем табличку
        for(int i = this->ui->tw_users_evlist->rowCount(); i >=0 ; i--){
            QTableWidgetItem * wit = this->ui->tw_users_evlist->takeItem(i,3);
            delete wit;
            wit = this->ui->tw_users_evlist->takeItem(i,2);
            delete wit;
            wit = this->ui->tw_users_evlist->takeItem(i,1);
            delete wit;
            wit = this->ui->tw_users_evlist->takeItem(i,0);
            delete wit;
        }

        // заполняем табличку
                this->ui->tw_users_evlist->setRowCount(variant.toList().size()/5);
                int currentRow=0;
                for( int i = 0 ; i < variant.toList().size(); i=i+5){
                    QTableWidgetItem * wit = new QTableWidgetItem;
                    wit->setText(variant.toList().at(i).toString());
                    wit->setToolTip(variant.toList().at(i+3).toString());
                    this->ui->tw_users_evlist->setItem(currentRow,0,wit);

                    wit = new QTableWidgetItem;
                    wit->setText(variant.toList().at(i+1).toString());
                    wit->setToolTip(variant.toList().at(i+3).toString());
                    this->ui->tw_users_evlist->setItem(currentRow,1,wit);

                    wit = new QTableWidgetItem;
                    wit->setText(variant.toList().at(i+4).toString());
                    wit->setToolTip(variant.toList().at(i+3).toString());
                    this->ui->tw_users_evlist->setItem(currentRow,2,wit);

                    wit = new QTableWidgetItem;
                    wit->setText(variant.toList().at(i+2).toString());
                    wit->setToolTip(variant.toList().at(i+3).toString());
                    this->ui->tw_users_evlist->setItem(currentRow,3,wit);

                    // красим в карсный цвет строки - ибо баланс нулевой
                    if(variant.toList().at(i+4).toString() == "0"){
                        this->ui->tw_users_evlist->item(currentRow,2)->setBackgroundColor("red");
                    }
                    currentRow++;
                }

    // выставляем выделенное событие по умолчанию, но если событий нет, блокируем кнопку перехода не след. этап
                if(this->ui->tw_users_evlist->rowCount() == 0){
                    this->ui->btn_stage1_next->setEnabled(false);
                }else{
                    this->ui->tw_users_evlist->setCurrentCell(0,0);
                    this->ui->btn_stage1_next->setEnabled(true);
                }

     this->ui->tw_users_evlist->resizeColumnsToContents();
     this->ui->tw_users_evlist->horizontalHeader()->setStretchLastSection(true);
     this->stlabel.setText(tr("OK"));
     this->centralWidget()->setEnabled(true);

    }

    // ответ на получение списка тарифов пользователю при продаже билета
    if( id == this->id_userTariffsList){
        qDebug()<<"user.tariffs.getlist";
        // очищаем табличку
        for(int i = this->ui->tw_stage2_table->rowCount(); i >=0 ; i--){
            QTableWidgetItem * wit = this->ui->tw_stage2_table->takeItem(i,1);
            delete wit;
            wit = this->ui->tw_stage2_table->takeItem(i,0);
            delete wit;
        }
        this->ui->tw_stage2_table->setRowCount(variant.toList().size()/2);
        int currentRow=0;
        for( int i = 0 ; i < variant.toList().size(); i=i+2){
            QTableWidgetItem * wit = new QTableWidgetItem;
            wit->setText(variant.toList().at(i).toString());
            this->ui->tw_stage2_table->setItem(currentRow,0,wit);
            wit = new QTableWidgetItem;
            wit->setText(variant.toList().at(i+1).toString());
            this->ui->tw_stage2_table->setItem(currentRow,1,wit);
            currentRow++;
        }
        if(this->ui->tw_stage2_table->rowCount() == 0){
            this->ui->btn_stage2_next->setEnabled(false);
        }else{
            this->ui->tw_stage2_table->setCurrentCell(0,0);
            this->ui->btn_stage2_next->setEnabled(true);
        }
        this->ui->tw_stage2_table->resizeColumnsToContents();
        this->ui->tw_stage2_table->horizontalHeader()->setStretchLastSection(true);
        this->stlabel.setText(tr("OK"));
        this->centralWidget()->setEnabled(true);

    }

    if(id == this->id_userSaleTicket){
        this->ticketNumber=variant.toList().at(0).toString();
        this->tuid=variant.toList().at(1).toString();
        this->isSaleOK = true;
        this->key_Sale = true;
    }

    if(id ==this->id_PLugRequest){
        qDebug()<<this->currentPlugRequest;
        QStringList aa;
        for(int i = 0 ; i < variant.toList().size(); i++){
            aa.append(variant.toList().at(i).toString());
        }
        emit this->sigPlugReguestFinish(this->currentPLug,
                                        this->currentPlugRequest,
                                        aa);
    }
    if( id == this->id_userReTicketInfo ){
        // прилетел ответ по информации билета
        // заполняем текстовку


        QFile a;
        a.setFileName(":/resources/reticket.html");
        a.open(QIODevice::ReadOnly | QIODevice::Text);
        // кракозябры блеять
        QString ht = QString::fromUtf8(a.readAll());

        ht.replace("$TUID$",variant.toList().at(0).toString());
        ht.replace("$USER$",variant.toList().at(1).toString());
        ht.replace("$EVENT$",variant.toList().at(2).toString());
        ht.replace("$TARIFF$",variant.toList().at(3).toString());
        ht.replace("$COST$",variant.toList().at(4).toString());
        ht.replace("$DATE$",variant.toList().at(5).toString());

        this->ui->tb_reticketinfo->document()->setHtml(ht);
        // возращяем управление
        this->stlabel.setText(tr("OK"));
        this->centralWidget()->setEnabled(true);
    }

    if( id == this->id_userReTicketBack ){
        // билет помечен как возвращенный. вертаем все на начало
        this->stlabel.setText(tr("OK"));
        this->centralWidget()->setEnabled(true);
        this->ui->sw_user->setCurrentIndex(SALE_STAGE_0);
    }

    if( id == this->id_user_tr){
        // прилетели данные с сервера.
        for(int i = this->ui->tw_tickets_tr->rowCount(); i >=0 ; i--){
            QTableWidgetItem * wit = this->ui->tw_tickets_tr->takeItem(i,5);
            delete wit;
            wit = this->ui->tw_tickets_tr->takeItem(i,4);
            delete wit;
            wit = this->ui->tw_tickets_tr->takeItem(i,3);
            delete wit;
            wit = this->ui->tw_tickets_tr->takeItem(i,2);
            delete wit;
            wit = this->ui->tw_tickets_tr->takeItem(i,1);
            delete wit;
            wit = this->ui->tw_tickets_tr->takeItem(i,0);
            delete wit;
        }

        this->ui->tw_tickets_tr->setRowCount(variant.toList().size()/9);
        int currentRow=0;
        int msum_saled = 0, msum_returned=0;
        for( int i = 0 ; i < variant.toList().size()/9; i++){
            QTableWidgetItem * wit = new QTableWidgetItem;
            wit->setText(variant.toList().at(i*9).toString());
            this->ui->tw_tickets_tr->setItem(i,0,wit);

            wit = new QTableWidgetItem;
            QString aa;
            aa.append(variant.toList().at(i*9+7).toString());
            aa.append("\n");
            aa.append(variant.toList().at(i*9+8).toString());
            wit->setText(aa);
            this->ui->tw_tickets_tr->setItem(i,1,wit);

            wit = new QTableWidgetItem;
            wit->setText(variant.toList().at(i*9+1).toString());
            this->ui->tw_tickets_tr->setItem(i,2,wit);

            wit = new QTableWidgetItem;
            wit->setText(variant.toList().at(i*9+3).toString());
            this->ui->tw_tickets_tr->setItem(i,3,wit);

            wit = new QTableWidgetItem;
            int mcost = variant.toList().at(i*9+2).toInt();
            wit->setText(QString::number(mcost));
            this->ui->tw_tickets_tr->setItem(i,4,wit);

            // статус
            QString st;
            QString col;
            if(variant.toList().at(i*9+4).toString() == "0"){
                // билет продан
                st.append(tr("Sold"));
                col = "green";
                msum_saled+=mcost;
            }else{
                // билет возвращен
                st.append(tr("Returned"));
                col = "red";
                msum_returned+=mcost;
            }
            wit = new QTableWidgetItem;
            wit->setText(st);
            wit->setBackgroundColor(col);
            this->ui->tw_tickets_tr->setItem(i,5,wit);

        }
        this->ui->tw_tickets_tr->resizeColumnsToContents();
        this->ui->tw_tickets_tr->resizeRowsToContents();
        this->ui->tw_tickets_tr->horizontalHeader()->setStretchLastSection(true);
        this->ui->le_tr->setText(tr("Sold tickets sum - %1\nReturned tickets sum- %2")
                                 .arg(QString::number(msum_saled))
                                 .arg(QString::number(msum_returned)));
        this->stlabel.setText(tr("OK"));
        this->centralWidget()->setEnabled(true);

    }

}

void MWin::slotFail(int id, int errcode, QString errstr){
    qDebug()<<"DEBUG ERROR "<<errcode<<" - "<<errstr;
    if(id == this->id_logon){
        this->lastError = errstr;
        this->dwait->slotStopError();
    }

    if(id == this->id_userReTicketInfo){
        QMessageBox::critical(this,tr("Error"),
                    tr("Error message from server:\n")+
                    QString("%1 - %2\n").arg(errcode).arg(errstr));
        this->stlabel.setText(tr("OK"));
        this->ui->sw_user->setCurrentIndex(RE_STAGE_1);
        this->centralWidget()->setEnabled(true);
    }else{


    if(id == this->id_adminEventAdd or id == this->id_adduser or id == this->id_admTariffsAdd){
        QMessageBox::critical(this,tr("Error"),
                    tr("Error message from server:\n")+
                    QString("%1 - %2\n").arg(errcode).arg(errstr));
        this->stlabel.setText(tr("OK"));
        this->centralWidget()->setEnabled(true);
    }else{
        if(id == this->id_userSaleTicket){
            // прилетела ошибка продажи
            QMessageBox::critical(this,tr("Error"),
                        tr("Error message from server:\n")+
                        QString("%1 - %2\n").arg(errcode).arg(errstr));
            this->isSaleOK = false;
            this->key_Sale = true;
        }
        else{
                // default error - exit
                QMessageBox::critical(this,tr("Error"),
                            tr("Error message from server:\n")+
                            QString("%1 - %2\n").arg(errcode).arg(errstr)+tr("exit."));
                        exit(errcode);
        }

    }
    }


}

bool MWin::eventFilter(QObject *obj, QEvent *event){
    if (event->type() == QEvent::ContextMenu and obj->objectName() == "tw_users" ) {        
        QMenu menu(this);        
            menu.addAction(this->actAddUser);
            menu.addAction(this->actEditUser);
            menu.addSeparator();
            menu.addAction(this->actDelUser);
            if(this->ui->tw_users->rowCount() == 0){
                this->actDelUser->setEnabled(false);
                this->actEditUser->setEnabled(false);
            }
            menu.exec(QCursor::pos());
            return true;
         } else {

        if(event->type() == QEvent::ContextMenu and obj->objectName() == "tw_events" ){
            QMenu menu(this);
            menu.addAction(this->actAdminEventsAdd);
            menu.addAction(this->actAdminEventsDublicate);
            menu.addAction(this->actAdminEventsEdit);
            menu.addSeparator();
            menu.addAction(this->actAdminEventsDelete);
            if(this->ui->tw_events->rowCount() == 0 ){
                this->actAdminEventsDelete->setEnabled(false);
                this->actAdminEventsDublicate->setEnabled(false);
                this->actAdminEventsEdit->setEnabled(false);
            }
            menu.exec(QCursor::pos());
        }else{

            if(event->type() == QEvent::ContextMenu and obj->objectName() == "tw_tariffs" ){
                QMenu menu(this);
                menu.addAction(this->actAdmTariffsAdd);
                menu.addAction(this->actAdmTariffsEdit);
                menu.addSeparator();
                menu.addAction(this->actAdmTariffsDel);
                if(this->ui->tw_tariffs->rowCount() == 0 ){
                    this->actAdmTariffsEdit->setEnabled(false);
                    this->actAdmTariffsDel->setEnabled(false);
                }
                menu.exec(QCursor::pos());
            }else{


             // standard event processing
             return QObject::eventFilter(obj, event);
        }
        }
        }
    return QObject::eventFilter(obj, event);

}

// функция добавления нового пользователя.
void MWin::slotAddUser(){
    // сначала показываем пустой диалог
    DiaUsers dia;
    if(dia.exec()){
        // данные введены, вынимаем их из диалога и упаковываем серверу
        QString uname=dia.getUsername();
        QString upass=dia.getUserpass();
        QString ucolor=dia.getColor();
        int utype=dia.getUserType();
        // небольшая проверка перед отправкой. имя пользователя и пароль должны быть
        if(uname.size()==0){
            QMessageBox::critical(this,tr("Error"),"Error - user name is fail");
        }else{
        if(upass.size()==0){
            QMessageBox::critical(this,tr("Error"),"Error - user password is fail");
        }else{
            // все хорошо, работаем дальше
            // блокируем окно
            this->centralWidget()->setEnabled(false);
            this->stlabel.setText(tr("Query add user"));
            // упаковываем и отсылаем данные
            QList<xmlrpc::Variant> np;
            np.append(this->username);
            np.append(this->hash);
            np.append(uname);
            np.append(upass);
            np.append(ucolor);
            np.append(utype);
            this->id_adduser = this->xmlclient->request("adduser",np);
        }
        }
    }
}
void MWin::slotEditUser(){
    //qDebug()<<"EDITTTT - "<<this->ui->tw_users->currentRow();
    // создаем диалог и заполняем поля.
    DiaUsers dia;
    QString olduname=this->ui->tw_users->item(this->ui->tw_users->currentRow(),2)->text();
    dia.setUsername(olduname);
    dia.setColor(this->ui->tw_users->item(this->ui->tw_users->currentRow(),1)->text());
    if(this->ui->tw_users->item(this->ui->tw_users->currentRow(),0)->text() == tr("Admin")){
        dia.setUserType(1);
    }
    if(dia.exec()){
        // диалог вернул изменения, вынимаем их и отдаем серверу в виде
        // старое имя и новые данные. имя же тоже может быть изменено.
        QString uname=dia.getUsername();
        QString upass=dia.getUserpass();
        QString ucolor=dia.getColor();
        int utype=dia.getUserType();
        // имя у пользователя должно быть, это без вариантов. а вот если в поле пароль пустота, то просто пароль не будет изменен.
        if(uname.size()==0){
            QMessageBox::critical(this,tr("Error"),"Error - user name is fail");
        }else{
            // все хорошо, работаем дальше
            // блокируем окно
            this->centralWidget()->setEnabled(false);
            this->stlabel.setText(tr("Query edit user"));
            // упаковываем и отсылаем данные
            QList<xmlrpc::Variant> np;
            np.append(this->username);
            np.append(this->hash);
            np.append(olduname);
            np.append(uname);
            np.append(upass);
            np.append(ucolor);
            np.append(QString::number(utype));
            this->id_edituser = this->xmlclient->request("edituser",np);
        }
    }
}
void MWin::slotDelUser(){
    // удаление пользователя, простой процесс.
    QString uname=this->ui->tw_users->item(this->ui->tw_users->currentRow(),2)->text();
    // спрашиваем разрешение на сие действие непотребное
    if(QMessageBox::question(this,tr("Delete?"),tr("Are you sure want to delete user \"%1\"")
                             .arg(uname),QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes){


    // блокируем окно
    this->centralWidget()->setEnabled(false);
    this->stlabel.setText(tr("Query del user"));
    // упаковываем и отсылаем данные
    QList<xmlrpc::Variant> np;
    np.append(this->username);
    np.append(this->hash);
    np.append(uname);
    this->id_deluser = this->xmlclient->request("deluser",np);
    }
}

void MWin::slottabW_admin(){
    qDebug()<<"Current tab is "<<this->ui->tabW_admin->currentIndex();
    switch(this->ui->tabW_admin->currentIndex()){
    case 0:
        // сейчас активная вкладка списка пользователей, перезапросим список
    {
        // блокируем окно
        this->centralWidget()->setEnabled(false);
        this->stlabel.setText(tr("Query userslist"));
        QList<xmlrpc::Variant> np;
        np.append(this->username);
        np.append(this->hash);
        this->id_getuserslist = this->xmlclient->request("getuserslist",np);
    }
        break;
    case 1:
        // сейчас активная вкладка списка событий админа, перезапросим список
        this->slotAdminEventsUpdate();
        break;
    case 2:
        // список тарифов
        this->slotAdmTariffsUpdate();
        break;
    case 3:
        // список отчетов
        break;
    default:
        break;
    }
}


void MWin::slotEventsAdminSetCurrentMonth(){
    // выставляем дефолтную дату в список начала и конца диапазона
    // списка событий для администратора
    QDateTime dtem,dten;
    QDate aa;
    aa.setYMD(QDate::currentDate().year(),QDate::currentDate().month(),1);
    dtem.setDate(aa);
    QTime tt;
    tt.setHMS(00,00,01);
    dtem.setTime(tt);
    aa.setYMD(QDate::currentDate().year(),QDate::currentDate().month(),QDate::currentDate().daysInMonth());
    tt.setHMS(23,59,59);
    dten.setDate(aa);
    dten.setTime(tt);

    this->ui->dte_de->setDateTime(dtem);
    this->ui->dte_gxis->setDateTime(dten);

}

void MWin::slotAdminEventsUpdate(){
    // необходимо обновить список отображаемых событий
    qDebug()<<"admin events update";
    // блокируем окно
    this->centralWidget()->setEnabled(false);
    this->stlabel.setText(tr("Query events list"));
    QList<xmlrpc::Variant> np;
    np.append(this->username);
    np.append(this->hash);
    np.append(this->ui->dte_de->dateTime().toString("yyyy-MM-dd hh:mm:ss"));
    np.append(this->ui->dte_gxis->dateTime().toString("yyyy-MM-dd hh:mm:ss"));
    this->id_adminEventsGet = this->xmlclient->request("adm.events.getlist",np);

}

void MWin::slotAdminEventsAdd(){
    // добавляем событие
    // запрашиваем список всех тарифов
    // блокируем окно
    this->centralWidget()->setEnabled(false);
    this->stlabel.setText(tr("Query tariffs"));

    this->key_adminEventAdd = false;
    QList<xmlrpc::Variant> np;
    np.append(this->username);
    np.append(this->hash);
    this->id_adminEventAddTL = this->xmlclient->request("adm.tariffs.getlist_for_events",np);
    while(!this->key_adminEventAdd){
        Sleeper::msleep(100);
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    }
    DiaEvents dia;
    // задаем список доступных тарифов
    dia.setTariffsList(this->tariffslist);
    this->stlabel.setText(tr("OK"));
    this->centralWidget()->setEnabled(true);
    if(dia.exec()){
        // данные введены, вынимаем их из диалога и упаковываем серверу
        QString ename = dia.getEvName();
        QString edesc = dia.getEvDesc();
        QString edate = dia.getEvDt().toString("yyyy-MM-dd hh:mm:ss");
        int ecap = dia.getEvCapacity();
        int estatus = dia.getEvStatus();
        QString tariffsEnabled = dia.getTariffsListEnabled();
        // блокируем окно
        this->centralWidget()->setEnabled(false);
        this->stlabel.setText(tr("Query add event"));
        // упаковываем и отсылаем данные
        QList<xmlrpc::Variant> np;
        np.append(this->username);
        np.append(this->hash);
        np.append(ename);
        np.append(edesc);
        np.append(edate);
        np.append(ecap);
        np.append(estatus);
        np.append(tariffsEnabled);
        this->id_adminEventAdd = this->xmlclient->request("adm.events.add",np);
    }
}
void MWin::slotAdminEventsDelete(){
    // спрашиваем разрешение на сие действие непотребное
    if(QMessageBox::question(this,tr("Delete?"),tr("Are you sure want to delete event \"%1\" and tickets for this event?")
                             .arg(this->ui->tw_events->item(this->ui->tw_events->currentRow(),4)->text()),
                             QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes){
    // блокируем окно
    this->centralWidget()->setEnabled(false);
    this->stlabel.setText(tr("Query add event"));
    // посылаем запрос на удаление события
    QList<xmlrpc::Variant> np;
    np.append(this->username);
    np.append(this->hash);
    np.append(this->ui->tw_events->item(this->ui->tw_events->currentRow(),4)->text());
    np.append(this->ui->tw_events->item(this->ui->tw_events->currentRow(),0)->text());
    this->id_adminEventDel = this->xmlclient->request("adm.events.del",np);
    }
}

void MWin::slotAdminEventsDublicate(){
 // функционал схож с редактированием только у клиента появляется диалог редактирования события которое сервер должен будет добавить.

    // блокируем окно
    this->centralWidget()->setEnabled(false);
    this->stlabel.setText(tr("Query tariffs"));

    QString oldename=this->ui->tw_events->item(this->ui->tw_events->currentRow(),4)->text();
    QString oldedate= this->ui->tw_events->item(this->ui->tw_events->currentRow(),0)->text();
    // заправшиваем у сервера список всех тарифов и список назначенных тарифов
    this->key_11 = false;
    QList<xmlrpc::Variant> np;
    np.append(this->username);
    np.append(this->hash);
    this->id_adminEventEditTL = this->xmlclient->request("adm.tariffs.getlist_aa",np);
    qDebug()<<"id = "<<this->id_adminEventEditTL;
    while(!this->key_11){
        Sleeper::msleep(100);
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    }
    this->key_adminEventEdit2 = false;
    QList<xmlrpc::Variant> np2;
    np2.append(this->username);
    np2.append(this->hash);
    np2.append(oldename);
    np2.append(oldedate);
    this->id_adminEventEditTEL = this->xmlclient->request("adm.tariffs.getlist_ab",np2);
    while(!this->key_adminEventEdit2){
        Sleeper::msleep(100);
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    }



    // создаем диалог и заполняем поля
    DiaEvents dia;
    dia.setTariffsList(this->tariffslist);
    dia.setTariffsListEnabled(this->tariffslistEnabled);
    dia.setEvName(oldename);
    dia.setEvDesc(this->ui->tw_events->item(this->ui->tw_events->currentRow(),4)->toolTip());
    dia.setEvCapacity(this->ui->tw_events->item(this->ui->tw_events->currentRow(),2)->text().toInt());
    if(this->ui->tw_events->item(this->ui->tw_events->currentRow(),1)->text() == tr("Opened")){
        dia.setEvStatus(ESTATE_OPENED);
    }else{
        if(this->ui->tw_events->item(this->ui->tw_events->currentRow(),1)->text() == tr("Closed")){
            dia.setEvStatus(ESTATE_CLOSED);
        }else{
            dia.setEvStatus(ESTATE_HIDED);
        }
    }
    dia.setEvDt(QDateTime::fromString(this->ui->tw_events->item(this->ui->tw_events->currentRow(),0)->text(),"yyyy-MM-dd hh:mm:ss"));
    this->stlabel.setText(tr("OK"));
    this->centralWidget()->setEnabled(true);
    if(dia.exec()){
        // диалог отработал, забираем данные
        QString ename = dia.getEvName();
        QString edesc = dia.getEvDesc();
        QString edate = dia.getEvDt().toString("yyyy-MM-dd hh:mm:ss");
        int ecap = dia.getEvCapacity();
        int estatus = dia.getEvStatus();
        QString tariffsEnabled = dia.getTariffsListEnabled();
        // имя у события обязательно должно быть.
        if(ename.size()==0){
            QMessageBox::critical(this,tr("Error"),"Error - event name is fail");
        }else{
            // все хорошо, работаем дальше
            // блокируем окно
            this->centralWidget()->setEnabled(false);
            this->stlabel.setText(tr("Query edit event"));
            // упаковываем и отсылаем данные
            QList<xmlrpc::Variant> np;
            np.append(this->username);
            np.append(this->hash);
            np.append(ename);
            np.append(edesc);
            np.append(edate);
            np.append(ecap);
            np.append(estatus);
            np.append(tariffsEnabled);
            this->id_adminEventEdit = this->xmlclient->request("adm.events.add",np);
        }
    }



}
void MWin::slotAdminEventsEdit(){
    // редактируем событие
    // блокируем окно
    this->centralWidget()->setEnabled(false);
    this->stlabel.setText(tr("Query tariffs"));
    QString oldename=this->ui->tw_events->item(this->ui->tw_events->currentRow(),4)->text();
    QString oldedate= this->ui->tw_events->item(this->ui->tw_events->currentRow(),0)->text();
    // заправшиваем у сервера список всех тарифов и список назначенных тарифов
    this->key_11 = false;
    QList<xmlrpc::Variant> np;
    np.append(this->username);
    np.append(this->hash);
    this->id_adminEventEditTL = this->xmlclient->request("adm.tariffs.getlist_aa",np);
    qDebug()<<"id = "<<this->id_adminEventEditTL;
    while(!this->key_11){
        QTime dieTime= QTime::currentTime().addMSecs(1);
        while( QTime::currentTime() < dieTime )
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    }
    this->key_adminEventEdit2 = false;
    QList<xmlrpc::Variant> np2;
    np2.append(this->username);
    np2.append(this->hash);
    np2.append(oldename);
    np2.append(oldedate);
    this->id_adminEventEditTEL = this->xmlclient->request("adm.tariffs.getlist_ab",np2);
    while(!this->key_adminEventEdit2){
        Sleeper::msleep(100);
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    }



    // создаем диалог и заполняем поля
    DiaEvents dia;
    dia.setTariffsList(this->tariffslist);
    dia.setTariffsListEnabled(this->tariffslistEnabled);
    dia.setEvName(oldename);
    dia.setEvDesc(this->ui->tw_events->item(this->ui->tw_events->currentRow(),4)->toolTip());
    dia.setEvCapacity(this->ui->tw_events->item(this->ui->tw_events->currentRow(),2)->text().toInt());
    if(this->ui->tw_events->item(this->ui->tw_events->currentRow(),1)->text() == tr("Opened")){
        dia.setEvStatus(ESTATE_OPENED);
    }else{
        if(this->ui->tw_events->item(this->ui->tw_events->currentRow(),1)->text() == tr("Closed")){
            dia.setEvStatus(ESTATE_CLOSED);
        }else{
            dia.setEvStatus(ESTATE_HIDED);
        }
    }
    dia.setEvDt(QDateTime::fromString(this->ui->tw_events->item(this->ui->tw_events->currentRow(),0)->text(),"yyyy-MM-dd hh:mm:ss"));
    this->stlabel.setText(tr("OK"));
    this->centralWidget()->setEnabled(true);
    if(dia.exec()){
        // диалог отработал, забираем данные
        QString ename = dia.getEvName();
        QString edesc = dia.getEvDesc();
        QString edate = dia.getEvDt().toString("yyyy-MM-dd hh:mm:ss");
        int ecap = dia.getEvCapacity();
        int estatus = dia.getEvStatus();
        QString tariffsEnabled = dia.getTariffsListEnabled();

        qDebug()<<"enabled tariffs list"<< tariffsEnabled;

        // имя у события обязательно должно быть.
        if(ename.size()==0){
            QMessageBox::critical(this,tr("Error"),"Error - event name is fail");
        }else{
            // все хорошо, работаем дальше
            // блокируем окно
            this->centralWidget()->setEnabled(false);
            this->stlabel.setText(tr("Query edit event"));
            // упаковываем и отсылаем данные
            QList<xmlrpc::Variant> np;
            np.append(this->username);
            np.append(this->hash);
            np.append(oldename);
            np.append(oldedate);
            np.append(ename);
            np.append(edesc);
            np.append(edate);
            np.append(ecap);
            np.append(estatus);
            np.append(tariffsEnabled);
            this->id_adminEventEdit = this->xmlclient->request("adm.events.edit",np);
        }
    }
}


void MWin::slotAdmTariffsAdd(){
    // сначала показываем пустой диалог
    DiaTariffs dia;
    if(dia.exec()){
        // данные введены, вынимаем их из диалога и упаковываем серверу
        QString tname=dia.getTariffName();
        int tcost=dia.getTariffCost();
        // необходимо проверить наличие имени тарифа, совпадать не должно
        bool isOkN=true;
        for(int i = 0 ; i < this->ui->tw_tariffs->rowCount(); i++){
            if(tname==this->ui->tw_tariffs->item(i,0)->text()){
                // имена совпали
                isOkN=false;
            }
        }
        if(!isOkN){
            QMessageBox::critical(this,tr("Error"),"Error - tariff name is fail");
        }else{
            // все хорошо, работаем дальше
            // блокируем окно
            this->centralWidget()->setEnabled(false);
            this->stlabel.setText(tr("Query add user"));
            // упаковываем и отсылаем данные
            QList<xmlrpc::Variant> np;
            np.append(this->username);
            np.append(this->hash);
            np.append(tname);
            np.append(tcost);
            this->id_admTariffsAdd = this->xmlclient->request("adm.tariffs.add",np);
        }
    }
}

void MWin::slotAdmTariffsEdit(){
    // создаем диалог и заполняем поля.
    DiaTariffs dia;
    QString oldtname=this->ui->tw_tariffs->item(this->ui->tw_tariffs->currentRow(),0)->text();
    dia.setTariffName(oldtname);
    dia.setTariffCost(this->ui->tw_tariffs->item(this->ui->tw_tariffs->currentRow(),1)->text().toInt());
    if(dia.exec()){
        // диалог вернул изменения, вынимаем их и отдаем серверу в виде
        // старое имя и новые данные. имя же тоже может быть изменено.
        QString tname=dia.getTariffName();
        int tcost=dia.getTariffCost();
        if(tname.size()==0){
            QMessageBox::critical(this,tr("Error"),"Error - tariff name is fail");
        }else{
            bool isOkN=true;
            for(int i = 0 ; i < this->ui->tw_tariffs->rowCount(); i++){
                if(tname==this->ui->tw_tariffs->item(i,0)->text()){
                    // имена совпали
                    isOkN=false;
                }
            }
            if(!isOkN){
                QMessageBox::critical(this,tr("Error"),"Error - tariff name is fail");
            }else{
            // все хорошо, работаем дальше
            // блокируем окно
            this->centralWidget()->setEnabled(false);
            this->stlabel.setText(tr("Query edit user"));
            // упаковываем и отсылаем данные
            QList<xmlrpc::Variant> np;
            np.append(this->username);
            np.append(this->hash);
            np.append(oldtname);
            np.append(tname);
            np.append(tcost);
            this->id_admTariffsEdit = this->xmlclient->request("adm.tariffs.edit",np);
            }
        }
    }
}

void MWin::slotAdmTariffsDel(){
    // удаление тарифа
    QString tname=this->ui->tw_tariffs->item(this->ui->tw_tariffs->currentRow(),0)->text();
    // спрашиваем разрешение на сие действие непотребное
    if(QMessageBox::question(this,tr("Delete?"),tr("Are you sure want to delete tariff \"%1\"")
                             .arg(tname),QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes){


    // блокируем окно
    this->centralWidget()->setEnabled(false);
    this->stlabel.setText(tr("Query del tariff"));
    // упаковываем и отсылаем данные
    QList<xmlrpc::Variant> np;
    np.append(this->username);
    np.append(this->hash);
    np.append(tname);
    this->id_admTariffsDel = this->xmlclient->request("adm.tariffs.del",np);
    }

}

void MWin::slotAdmTariffsUpdate(){
    // необходимо обновить список отображаемых тарифов
    qDebug()<<"admin tarifs update";
    // блокируем окно
    this->centralWidget()->setEnabled(false);
    this->stlabel.setText(tr("Query tariffs list"));
    QList<xmlrpc::Variant> np;
    np.append(this->username);
    np.append(this->hash);
    this->id_admTariffsGet = this->xmlclient->request("adm.tariffs.getlist",np);
}


void MWin::slotSaleStage1(){
    // выставляем этап
    this->ui->sw_user->setCurrentIndex(SALE_STAGE_1);
    // заполняем поля дат с текущего дня на неделю
    this->slotEventsUserSetCurrentWeek();
    this->slotSaleUpdateEventsList();
}

void MWin::slotSaleUpdateEventsList(){
    // делаем запрос списка событий для пользователя
    this->centralWidget()->setEnabled(false);
    this->stlabel.setText(tr("Query events list"));
    QList<xmlrpc::Variant> np;
    np.append(this->username);
    np.append(this->hash);
    np.append(this->ui->dte_de_user_evlist->dateTime().toString("yyyy-MM-dd hh:mm:ss"));
    np.append(this->ui->dte_gxis_user_evlist->dateTime().toString("yyyy-MM-dd hh:mm:ss"));
    this->id_userEventsList  = this->xmlclient->request("user.events.getlist",np);
}

void MWin::slotSaleStage1back(){
    this->ui->sw_user->setCurrentIndex(SALE_STAGE_0);
}

void MWin::slotEventsUserSetCurrentWeek(){
    QDateTime dtem,dten;
    QDate aa;
    aa.setYMD(QDate::currentDate().year(),
              QDate::currentDate().month(),
              QDate::currentDate().day());
    dtem.setDate(aa);
    QTime tt;
    tt.setHMS(00,00,01);
    dtem.setTime(tt);
    tt.setHMS(23,59,59);
    dten.setTime(tt);
    dten.setDate(aa);
    this->ui->dte_de_user_evlist->setDateTime(dtem);
    this->ui->dte_gxis_user_evlist->setDateTime(dten.addDays(7));
}

void MWin::slotSaleStage1next(){
    this->ui->sw_user->setCurrentIndex(SALE_STAGE_2);
    this->slotSaleUpdateTariffsList();
}

void MWin::slotSaleUpdateTariffsList(){
    // обновляем список тарифов для выбранного события
    this->centralWidget()->setEnabled(false);
    this->stlabel.setText(tr("Query tariffs list"));
    QList<xmlrpc::Variant> np;
    np.append(this->username);
    np.append(this->hash);
    np.append(this->ui->tw_users_evlist->item(this->ui->tw_users_evlist->currentRow(),3)->text());
    np.append(this->ui->tw_users_evlist->item(this->ui->tw_users_evlist->currentRow(),0)->text());
    this->id_userTariffsList  = this->xmlclient->request("user.tariffs.getlist",np);
}


void MWin::slotSaleStage2back(){
    this->ui->sw_user->setCurrentIndex(SALE_STAGE_1);
    this->slotSaleUpdateEventsList();
}

void MWin::slotSaleStage2next(){
    this->ui->sw_user->setCurrentIndex(SALE_STAGE_3);
    // показываем документ билета
    QFile a;
    a.setFileName(":/resources/ticket.html");
    a.open(QIODevice::ReadOnly | QIODevice::Text);
    // кракозябры блеять
    QString ht = QString::fromUtf8(a.readAll());

    // ставим заголовок
    ht.replace("$event_name$",this->ui->tw_users_evlist->item(this->ui->tw_users_evlist->currentRow(),3)->text());
    // формируем дату число - месяц - год час:минуты
    QDateTime dt = QDateTime::fromString(this->ui->tw_users_evlist->item(this->ui->tw_users_evlist->currentRow(),0)->text(),"yyyy-MM-dd hh:mm:ss");
    ht.replace("$date$",dt.toString("dd.MM.yyyy hh:mm"));
    ht.replace("$text$",this->ui->tw_users_evlist->item(this->ui->tw_users_evlist->currentRow(),3)->toolTip());
    ht.replace("$tariff$",this->ui->tw_stage2_table->item(this->ui->tw_stage2_table->currentRow(),0)->text());
    ht.replace("$cost$",this->ui->tw_stage2_table->item(this->ui->tw_stage2_table->currentRow(),1)->text());
    this->ui->tb_ticket->document()->setHtml(ht);

}


void MWin::slotSalePrint(){

    QTextDocument *document = this->ui->tb_ticket->document();
    QPrinter printer;

    QPrintDialog *dia = new QPrintDialog(&printer,this);
    // билет отправлен на печать, совершаем покупку и печатаем
    this->centralWidget()->setEnabled(false);
    this->stlabel.setText(tr("Query sale ticket"));
    QList<xmlrpc::Variant> np;
    // кто продает
    np.append(this->username);
    // в какой сессии
    np.append(this->hash);
    // наименование события
    np.append(this->ui->tw_users_evlist->item(this->ui->tw_users_evlist->currentRow(),3)->text());
    // дата события
    np.append(this->ui->tw_users_evlist->item(this->ui->tw_users_evlist->currentRow(),0)->text());
    // наименование тарифа
    np.append(this->ui->tw_stage2_table->item(this->ui->tw_stage2_table->currentRow(),0)->text());
    // цена билета
    np.append(this->ui->tw_stage2_table->item(this->ui->tw_stage2_table->currentRow(),1)->text());

    this->id_userSaleTicket  = this->xmlclient->request("user.ticket.sale",np);
    // ожидаем ответа от сервера.
    this->isSaleOK = false;
    while(!this->key_Sale){
        Sleeper::msleep(100);
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    }
    // прилетел ответ, смотрим статус
    if(this->isSaleOK){
            if(dia->exec() == QPrintDialog::Accepted){
                // все хорошо, билет продан, можно печатать.
                this->ui->tb_ticket->document()->setHtml(this->ui->tb_ticket->document()->toHtml().replace("$TicketNumber$",this->ticketNumber));
                this->ui->tb_ticket->document()->setHtml(this->ui->tb_ticket->document()->toHtml().replace("$TUID$",this->tuid));
               printer.setPageMargins(2.5,2.5,2.5,2.5,QPrinter::Millimeter);
               document->print(&printer);
            }

            this->ticketNumber="";
            this->isSaleOK = false;
            this->key_Sale = false;
            this->slotSaleUpdateEventsList();
            this->ui->sw_user->setCurrentIndex(SALE_STAGE_0);
    }else{
       // беда, билет не продан, что то с базой или какая другая ерунда.
       // откатываемся на начало - список событий
        this->slotSaleUpdateEventsList();
       this->ui->sw_user->setCurrentIndex(SALE_STAGE_0);
    }
}


void MWin::slotReport(){
    // запустили отчет, вызываем диалог плагина, вся остальная магия происходит там.
    this->reptList.at(this->ui->lw_reports->currentRow())->execDia();
}

void MWin::slotPlugRequestStart(const QString &plugName, const QString &requestName, QStringList params){
    qDebug()<<"plugin - "<<plugName<<" request - "<<requestName;
    qDebug()<<"params"<<params;
    // упаковываем данные и делаем запрос, предварительно выставив флаг работы с плагинами
    this->currentPLug = plugName;
    this->currentPlugRequest = requestName;
    QList<xmlrpc::Variant> np;
    np.append(this->username);
    np.append(this->hash);
    for(int i = 0 ; i < params.size(); i++){
        np.append(params.at(i));
    }
    this->id_PLugRequest = this->xmlclient->request(requestName,np);
}


// возврат билета
void MWin::slotReStage1(){
    // выставляем этап
    this->ui->sw_user->setCurrentIndex(RE_STAGE_1);
}


// юзверь отменил возврат билета кажем первый экран
void MWin::slotReStage1back(){
    this->ui->sw_user->setCurrentIndex(SALE_STAGE_0);
}


// делаем запрос серверу
void MWin::slotReStage1next(){
    // блокируемся
    this->centralWidget()->setEnabled(false);
    this->stlabel.setText(tr("Query ticket info"));
    this->ui->sw_user->setCurrentIndex(RE_STAGE_2);
    // вынимаем TUID
    QList<xmlrpc::Variant> np;
    np.append(this->username);
    np.append(this->hash);
    np.append(this->ui->le_tuid->text());
    this->id_userReTicketInfo = this->xmlclient->request("user.reticket.info",np);
}

void MWin::slotReStage2back(){
    this->ui->sw_user->setCurrentIndex(RE_STAGE_1);
}

void MWin::slotReStage2cancel(){
    this->ui->le_tuid->clear();
    this->ui->sw_user->setCurrentIndex(SALE_STAGE_0);
}

void MWin::slotReStage2next(){
    // необходимо сделать запрос удаления билета с текущим tuid.
    // точнее будет не удаление а пометка как возвращенный билет
    // блокируемся
    this->centralWidget()->setEnabled(false);
    this->stlabel.setText(tr("Query ticket back"));
    this->ui->sw_user->setCurrentIndex(RE_STAGE_2);
    // вынимаем TUID
    QList<xmlrpc::Variant> np;
    np.append(this->username);
    np.append(this->hash);
    np.append(this->ui->le_tuid->text());
    this->id_userReTicketBack = this->xmlclient->request("user.reticket.back",np);
}

void MWin::slotSaleStage2cancel(){
    this->ui->sw_user->setCurrentIndex(SALE_STAGE_0);
}

void MWin::slotAboutQt(){
    QMessageBox::aboutQt(this,tr("About Qt4"));
}

void MWin::slotAbout(){
    QFile a;
    a.setFileName(":/resources/about.html");
    a.open(QIODevice::ReadOnly | QIODevice::Text);
    // кракозябры блеять
    QString ab = QString::fromUtf8(a.readAll());
    ab.replace("%P_VERSION%",VERSION);
    ab.replace("%P_BUILD%",GIT_HASH);
    QMessageBox::about(this,tr("About program"),ab);
}

void MWin::slotUser_tr(){
    // заполняем по умолчанию текущую неделю
    this->slotUser_tr_currentWeek();
    this->ui->sw_user->setCurrentIndex(USER_TR_1);

}

void MWin::slotUser_tr_currentWeek(){
    QDateTime dtem,dten;
    QDate aa;
    aa.setYMD(QDate::currentDate().year(),
              QDate::currentDate().month(),
              QDate::currentDate().day());
    dtem.setDate(aa);
    QTime tt;
    tt.setHMS(00,00,01);
    dtem.setTime(tt);
    tt.setHMS(23,59,59);
    dten.setTime(tt);
    dten.setDate(aa);
    this->ui->dte_from_tr->setDateTime(dtem);
    this->ui->dte_to_rt->setDateTime(dten.addDays(7));
    this->slotUser_tr_getlist();
}

void MWin::slotUser_tr_getlist(){
    this->centralWidget()->setEnabled(false);
    this->stlabel.setText(tr("Query tickets list"));
    QList<xmlrpc::Variant> np;
    np.append(this->username);
    np.append(this->hash);
    np.append(this->ui->dte_from_tr->dateTime().toString("yyyy-MM-dd hh:mm:ss"));
    np.append(this->ui->dte_to_rt->dateTime().toString("yyyy-MM-dd hh:mm:ss"));
    this->id_user_tr  = this->xmlclient->request("user.rpt.ticketslist",np);
}
